// Final Project
// CS210
// Members: William McPherson, Brian Gale, Jesse Hardman, Matt Wildschuetz 
#include "game.h"
#include <sstream>

//background stuff
const int BUFFERW = SCREEN_WIDTH * 2; // Screen buffer width
const int BUFFERH = SCREEN_HEIGHT * 2; // Screen buffer height
const int BG_WIDTH = 640; // Background image width
const int BG_HEIGHT = 480; // Background image height
LPDIRECT3DSURFACE9 back; // Background surface
long scrollx=0, scrolly=0; // Long variables for scrolling

// Font, useful for HUD elements
LPD3DXFONT font;
LPD3DXFONT title;

//sprite handler
LPD3DXSPRITE sprite_handler;

//ball sprite
LPDIRECT3DTEXTURE9 ball_image;
SPRITE ball;

// Player sprite
LPDIRECT3DTEXTURE9 player_image;
SPRITE player;

// Wood block platform
#define NUM_OF_BAD 2 // Number of wooden blocks, make sure to update this if you want more blocks
LPDIRECT3DTEXTURE9 bad_image1;
SPRITE badGuy[NUM_OF_BAD];
SPRITE enemy;
bool bad_kill[NUM_OF_BAD]; //flag to check if bad guys have been KIA
int playerHealth = 5; // Number of hits the player can take

//the wave sound
CSound *sound_bounce;
CSound *sound_hit;
CSound *music;

//misc
long start = GetTickCount();
HRESULT result;

//---------------------------------------------------------------------------------------
//initializes the game
int Game_Init(HWND hwnd)
{
	//set random number seed
	srand(time(NULL));

	//initialize mouse
	if (!Init_Mouse(hwnd))
	{
		MessageBox(hwnd, "Error initializing the mouse", "Error", MB_OK);
		return 0;
	}

	//initialize keyboard
	if (!Init_Keyboard(hwnd))
	{
		MessageBox(hwnd, "Error initializing the keyboard", "Error", MB_OK);
		return 0;
	}

	//create sprite handler object
	result = D3DXCreateSprite(d3ddev, &sprite_handler);
	if (result != D3D_OK)
		return 0;

	//load the background image
	LPDIRECT3DSURFACE9 image = NULL;
	// You have to add two backslashes when using an image in a subfolder
	image = LoadSurface("Game Sprites\\rocks_bg.bmp", NULL);
	if (image == NULL)
		return 0;

	//create background
	HRESULT result = 
		d3ddev->CreateOffscreenPlainSurface(
		BUFFERW,
		BUFFERH,
		D3DFMT_X8R8G8B8,
		D3DPOOL_DEFAULT,
		&back,
		NULL);
	if (result != D3D_OK) return false;

	// ===========================
	// Copy images for scrolling
	// ===========================

	//copy image to upper left corner of background
	RECT source_rect = {0, 0, BG_WIDTH, BG_HEIGHT };
	RECT dest_ul = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
	d3ddev->StretchRect(image, &source_rect, back, &dest_ul, D3DTEXF_NONE);

	//copy image to upper right corner of background
	RECT dest_ur = { SCREEN_WIDTH, 0, SCREEN_WIDTH*2, SCREEN_HEIGHT };
	d3ddev->StretchRect(image, &source_rect, back, &dest_ur, D3DTEXF_NONE);

	//copy image to lower left corner of background
	RECT dest_ll = { 0, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT*2 };
	d3ddev->StretchRect(image, &source_rect, back, &dest_ll, D3DTEXF_NONE);

	//copy image to lower right corner of background
	RECT dest_lr = { SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH*2, SCREEN_HEIGHT*2 };
	d3ddev->StretchRect(image, &source_rect, back, &dest_lr, D3DTEXF_NONE);

	//get pointer to the back buffer
	d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);


	//remove image
	image->Release();

	// Load player sprite
	player_image = LoadTexture("Game Sprites\\EdwardElricRun.bmp",D3DCOLOR_XRGB(0,150,0));
	if (player_image == NULL)
		return 0;

	// Where the player starts
	player.x = 300;
	player.y = SCREEN_HEIGHT - 100;
	player.curframe = 0; // First frame in animation, current frame.
	player.firstframe = 0; // Always equals the first frame in animation
	player.lastframe = 6; // Last frame in animation
	player.animdelay = 3; // Delay between frames
	player.animcount = 0; // Always set to zero
	// Player sprite width/height
	player.width = 57;
	player.height = 58;
	player.movex = 5; // Used for walking
	player.movey = 10; // Used for jumping/falling

//load bad guy
	bad_image1 = LoadTexture("Game Sprites\\kekashi.bmp",D3DCOLOR_XRGB(0,150,0));
	if (bad_image1 == NULL)
		return 0;
	enemy.width = 93;
	enemy.height = 77;
	enemy.x = 900;
	enemy.y = SCREEN_HEIGHT - 120;
	enemy.curframe = 0;
	enemy.firstframe = 0;
	enemy.lastframe = 25;
	enemy.animdelay = 3;
	enemy.animcount = 0;
	enemy.movex = 0;



	for(int i = 0; i < NUM_OF_BAD; i++)
	{
		bad_kill[i] = false;
	}//loop to flag bool value 

	//load bounce wave file
	sound_bounce = LoadSound("bounce.wav");
	if (sound_bounce == NULL)
		return 0;

	//load the hit wave file
	sound_hit = LoadSound("hit.wav");
	if (sound_hit == NULL)
		return 0;

	music=LoadSound("Rock_Hop.wav");
	if (music == NULL)
		return 0;

	// Create the font
	font = MakeFont("Arial",24);
	title = MakeFont("Chiller",32);

	//return okay
	return 1;
}
//---------------------------------------------------------------------------------------
// Collision detection function
//---------------------------------------------------------------------------------------
int Collision(SPRITE sprite1, SPRITE sprite2)
{
	RECT rect1;
	rect1.left = sprite1.x+1;
	rect1.top = sprite1.y+1;
	rect1.right = sprite1.x + sprite1.width-1;
	rect1.bottom = sprite1.y + sprite1.height-1;

	RECT rect2;
	rect2.left = sprite2.x+1;
	rect2.top = sprite2.y+1;
	rect2.right = sprite2.x + sprite2.width-1;
	rect2.bottom = sprite2.y + sprite2.height-1;

	RECT dest;
	return IntersectRect(&dest, &rect1, &rect2);
}
//---------------------------------------------------------------------------------------
//the main game loop
void Game_Run(HWND hwnd)
{
	static bool playerRight = true; // Variable that tells us which direction player is moving
	static int player_starty = player.y; // Store where the player Y starts, as set above
	int player_maxy = player_starty - 150; // Maximum jumping height, in pixels
	static bool player_jumping = false; // Player jumping flag
	static bool player_falling = false; // Player falling flag
	static bool player_attacking = false; // Player attacking flag
	static bool enemy_atk = false;
	// For current animation, defaults to stand/run animation
	//	Would put these up above, but they probably need to be in this function (Game_Run)
	int columns = 7; // Number of columns
	int rows = 1; // Number of rows
	static bool dontScrollBg = false; // Set to true when you don't want the background to scroll,
	//	even when it normally would



	//ball position vector
	D3DXVECTOR3 position(0,0,0);   
	D3DXVECTOR3 position1(0,0,0);

	//make sure the Direct3D device is valid
	if (d3ddev == NULL)
		return;

	//update mouse and keyboard
	//Poll_Mouse();
	Poll_Keyboard();

	//after short delay, ready for next frame?
	//this keeps the game running at a steady frame rate
	if (GetTickCount() - start >= 30)
	{
		//reset timing
		start = GetTickCount();

		
			if(++enemy.animcount > enemy.animdelay)
			{
			enemy.animcount = 0;
				
				if(++enemy.curframe > enemy.lastframe)
				{
					enemy.curframe = 0;
				}
				if(enemy.curframe == 2)
				{
					enemy.animdelay = 7;
				}
	
				if(enemy.curframe == 10)
				{
					enemy.animdelay = 3;
					enemy.movex= 150;
					enemy.x -= enemy.movex;
				}
			}
	


		// Make player jump while we pres the Z key
		if (Key_Down(DIK_Z) && !player_falling)
		{
			player_jumping = true; // Set player jumping flag


			if(player.y != player_maxy)
			{
				// Move player upwards
				player.y -= player.movey;
				// Jumping animation from standstill
				if(!Key_Down(DIK_LEFT) && !Key_Down(DIK_RIGHT))
				{
					columns = 4;	
					player.width = 48;
					player.height = 76;
					if(playerRight)
					{
						player_image = LoadTexture("Game Sprites\\EdwardJumpRight.bmp",D3DCOLOR_XRGB(0,150,0));
						player.curframe = 1;
					}
					else
					{
						player_image = LoadTexture("Game Sprites\\EdwardJumpLeft.bmp",D3DCOLOR_XRGB(0,150,0));
						player.curframe = 1;
					}
				}
			}
			else
			{
				// Player reaches maximum height, bring him down
				player_falling = true;
			}
		}

		// Gravity, aka bring the player down
		if(player_falling == true || !Key_Down(DIK_Z) && player_jumping == true)
		{


			if(player.y != player_starty)
			{
				// Player has not reached starting Y again, bring him down
				player_falling = true;
				player.y += player.movey;
			}
			else
			{
				// Player is now on the ground, he is neither falling nor jumping
				player_falling = false;
				player_jumping = false;
			}
		}

		// Make the player attack
		if(Key_Down(DIK_X) && !player_jumping && !player_falling &&
			!Key_Down(DIK_LEFT) && !Key_Down(DIK_RIGHT))
		{
			player_attacking = true; // Show that we are now attacking
			// Change sprite information, because we're using a different sprite shet
			columns = 4;
			player.lastframe = 3;
			player.width = 59;
			player.height = 60;
			// Play attack animation, facing right
			if(playerRight)
			{
				player_image = LoadTexture("Game Sprites\\EdwardPunchRight.bmp" , D3DCOLOR_XRGB(0,150,0));
				if(++player.animcount > player.animdelay)
				{
					player.animcount = 0;

					if(++player.curframe > player.lastframe)
					{
						player.curframe = 0; // Reset animatino
						PlaySound(sound_hit); // Play sound
					}
				}
			}
			// Play attack animation, facing left
			else
			{
				player_image = LoadTexture("Game Sprites\\EdwardPunchLeft.bmp" , D3DCOLOR_XRGB(0,150,0));
				if(++player.animcount > player.animdelay)
				{
					player.animcount = 0;

					if(--player.curframe < player.firstframe)
					{
						player.curframe = player.lastframe; // Reset animation
						PlaySound(sound_hit); // Play sound
					}
				}
			}
		}
		else
		{
			// Reset player state
			player_attacking = false;
			// Change sprite information back
			columns = 6;
			player.lastframe = 6;
			player.width = 57;
			player.height = 58;
			// Load the correctly facing sprite sheet
			if(playerRight)
				player_image = LoadTexture("Game Sprites\\EdwardElricRun.bmp" , D3DCOLOR_XRGB(0,150,0));
			else
				player_image = LoadTexture("Game Sprites\\EdwardElricRunLeft.bmp" , D3DCOLOR_XRGB(0,150,0));
		}

		// Keep the player in the boundries
		if (player.x > (SCREEN_WIDTH - 150) - player.width)
			player.x = (SCREEN_WIDTH - 150) - player.width;
		else if (player.x < 150)
			player.x = 150;

		// Move player left while left key is pressed
		if (Key_Down(DIK_LEFT) && !Key_Down(DIK_RIGHT))
		{
			playerRight = false;
			// Load running to the right sprites
			// Move player based on movex
			player.x -= player.movex;

			if(player_jumping == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardJumpLeft.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 1; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else if(player_falling == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardFallingLeft.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 1; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else
			{
				// Load running to the right sprites
				player_image = LoadTexture("Game Sprites\\EdwardElricRunLeft.bmp" , D3DCOLOR_XRGB(0,150,0));
			}

			// Animate player
			if(++player.animcount > player.animdelay)
			{
				player.animcount = 0;

				if(--player.curframe < player.firstframe)
				{

					if (player_jumping || player_falling )
					{
						player.curframe = 3;
					}
					else
					{
						player.curframe = 5;
					}

				}
			}
		}
	if (bad_image1 == NULL)
	{
		MessageBox(hwnd, "You beat the damn GAME", "GOOD FOR YOU", MB_OK);
		PostMessage(hwnd, WM_DESTROY, 0, 0);
	}
		// Move player right while left key is pressed
		if (Key_Down(DIK_RIGHT) && !Key_Down(DIK_LEFT))
		{
			playerRight = true;
			// Move player based on movex
			player.x += player.movex;

			if(player_jumping == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardJumpRight.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 3; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else if(player_falling == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardFallingRight.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 3; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else
			{
				// Load running to the right sprites
				player_image = LoadTexture("Game Sprites\\EdwardElricRun.bmp" , D3DCOLOR_XRGB(0,150,0));
			}
			// Animate player
			if(++player.animcount > player.animdelay)
			{
				player.animcount = 0;

				if(++player.curframe > player.lastframe)
				{
					player.curframe = 1;
				}
			}
		}
		// if statement for if player is not pressing right or left the person will do the jump animation
		if(!Key_Down(DIK_LEFT) && !Key_Down(DIK_RIGHT) && !player_attacking )
		{
			if(playerRight == true && player_jumping == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardJumpRight.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 3; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else if(playerRight == true && player_falling == true)
			{
				player_image = LoadTexture("Game Sprites\\EdwardFallingRight.bmp",D3DCOLOR_XRGB(0,150,0));
				columns = 4;	
				player.lastframe = 3; // Last frame in animation
				player.width = 48;
				player.height = 76;
				player.animdelay = 3;
			}
			else
			{
				if(!playerRight && player_jumping == true)
				{
					player_image = LoadTexture("Game Sprites\\EdwardJumpLeft.bmp",D3DCOLOR_XRGB(0,150,0));
					columns = 4;	
					player.lastframe = 3; // Last frame in animation
					player.width = 48;
					player.height = 76;
					player.animdelay = 3;
				}
				else if(!playerRight && player_falling == true)
				{
					player_image = LoadTexture("Game Sprites\\EdwardFallingLeft.bmp",D3DCOLOR_XRGB(0,150,0));
					columns = 4;	
					player.lastframe = 3; // Last frame in animation
					player.width = 48;
					player.height = 76;
					player.animdelay = 3;
				}
			}
		}
		// Reset player frames if not pressing any keys or moving anywhere
		if(!Key_Down(DIK_LEFT) && !Key_Down(DIK_RIGHT) && !player_attacking &&
			!player_jumping && !player_falling)
		{
			if(playerRight == true)
			{
				player.curframe = 0;
			}
			else
			{
				player.curframe = 6;
			}
		}


		//see if player has touched bad guy	
		if(Collision(player, enemy) && player_attacking == true && bad_image1 != NULL)
		{		
			bad_image1 = NULL;			
		}

		// Hurt and push back player if he's not attacking
		if(Collision(player, enemy) && player_attacking == false && bad_image1 != NULL)
		{
			// Teleport player backwards
			player.x = player.x - 100;
			// Decrement playerhealth
			playerHealth--;
		}

	// Scroll background when player reaches point near edge of the screen
	if (Key_Down(DIK_LEFT) && player.x <= 250 && !dontScrollBg)
	{
		scrollx -= 5; // Scroll 5 pixels per step
		enemy.x += 5;//anchor enemy when scrolling
	}


	if (Key_Down(DIK_RIGHT) && player.x >= (SCREEN_WIDTH - 250) && !dontScrollBg)
	{
		scrollx += 5;
		enemy.x -= 5;//anchor enemy when scrolling
	}

	// keep scrolling within boundary
	if (scrolly < 0)
		scrolly = BUFFERH - SCREEN_HEIGHT;
	if (scrolly > BUFFERH - SCREEN_HEIGHT)
		scrolly = 0;
	if (scrollx < 0)
		scrollx = BUFFERW - SCREEN_WIDTH;
	if (scrollx > BUFFERW - SCREEN_WIDTH)
		scrollx = 0;
}
	//   Poll_Mouse();
	//start rendering
	if (d3ddev->BeginScene())
	{
		//erase the entire background
		//d3ddev->StretchRect(back, NULL, backbuffer, NULL, D3DTEXF_NONE);
		// ===========================
		// Scrolling background
		// ===========================
		RECT source_rect = {scrollx, scrolly, scrollx+SCREEN_WIDTH, scrolly+SCREEN_HEIGHT };
		RECT dest_rect = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};

		d3ddev->StretchRect(back, &source_rect, backbuffer, &dest_rect, D3DTEXF_NONE);

		//start sprite handler
		sprite_handler->Begin(D3DXSPRITE_ALPHABLEND);



		//draw the player
		RECT srcRect;
		position.x = (float)player.x;
		position.y = (float)player.y;

		srcRect.left = (player.curframe % columns) * player.width;
		srcRect.top = (player.curframe / columns) * player.height;
		srcRect.right = srcRect.left + player.width;
		srcRect.bottom = srcRect.top + player.height;
		sprite_handler->Draw(
			player_image,
			&srcRect,
			NULL,
			&position,
			D3DCOLOR_XRGB(255,255,255));

		//draws enemy sprites
		RECT srcRect1;
		position1.x = (float)enemy.x;
		position1.y = (float)enemy.y;
		srcRect1.left = (enemy.curframe % columns) * enemy.width;
		srcRect1.top = (enemy.curframe / columns) * enemy.height;
		srcRect1.right = srcRect1.left + enemy.width;
		srcRect1.bottom = srcRect1.top + enemy.height;
		sprite_handler->Draw(
			bad_image1,
			&srcRect1,
			NULL,
			&position1,
			D3DCOLOR_XRGB(255,255,255));


		// Draw life counter
		// convert to a string
		char temp[3];
		sprintf(temp,"%d",playerHealth);
		string s = temp;
		FontPrint(font, 60, 50, s);
		FontPrint(title, 250, 2, "Diablo Slayer");

		//stop drawing
		sprite_handler->End();

		//stop rendering
		d3ddev->EndScene();
	}

	//display the back buffer on the screen
	d3ddev->Present(NULL, NULL, NULL, NULL);

	//check for mouse button (to exit program)
	if (Mouse_Button(0))
	{
		PostMessage(hwnd, WM_DESTROY, 0, 0);
	}
	// close game if player health reaches zero
	if(playerHealth == 0)
		PostMessage(hwnd, WM_DESTROY, 0, 0);
	//check for escape key (to exit program)
	if (Key_Down(DIK_ESCAPE))
		PostMessage(hwnd, WM_DESTROY, 0, 0);
	//loops background music
	if (!Key_Down(DIK_ESCAPE))
	{
		PlaySound(music);
	}
}
//---------------------------------------------------------------------------------------
//frees memory and cleans up before the game ends
void Game_End(HWND hwnd)
{

	if (bad_image1 != NULL)
		bad_image1->Release();

	if (player_image != NULL)
		player_image->Release();

	if (back != NULL)
		back->Release();

	if (sprite_handler != NULL)
		sprite_handler->Release();

}

//---------------------------------------------------------------------------------------